package com.ccx.coachsite.downloadmgr;



import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.ccx.coachsite.R;
import com.ccx.coachsite.api.CoachSiteSoftMgrApiAccessor;
import com.ccx.coachsite.bus.SharedKey;
import com.ccx.coachsite.data.SystemConst;
import com.ccx.coachsite.model.ServerDetailResult;
import com.ccx.coachsite.ui.softmgr.SoftInfo;
import com.ccx.coachsite.ui.softmgr.SoftMgrDetailActivity;
import com.ccx.coachsite.util.FileUtil;
import com.ccx.coachsite.util.LogUtil;
import com.ccx.coachsite.util.SharedPreferencesUtil;
import com.ccx.coachsite.util.StringUtil;
import com.ccx.coachsite.util.U;



/**
 * 软件下载服务
 *
 */
public class DownloadService extends Service {

	private final String TAG="DownloadService";

	private Bitmap mDefBmp;

	/**
	 * 下载服务对外广播任务的下载状态
	 */
	public final static String DOWNLOAD_STATUS_CHANGE_RECEIVER="coachsite.download.status.change.receiver";

	/**
	 * 下载队列
	 */
	private static HashMap<String, DownloadItem> mDownloadQueue;

	private List<Handler> mHandlerList;
	/**
	 * 前台界面注册进来的，用于更新前台界面的进度条
	 */
	private Handler mTopHanlder;

	/**
	 * 消除下载监听器的action
	 */
	public static final String RECEIVER_CANCEL_DOWNLOAD="receiver_cancel_download";
	/**
	 * 取消下载监听器
	 */
	private CancelDownloadReceiver mCancelDownloadReceiver;
	/**
	 * 正在下载的线程集合
	 */
	private static HashMap<String,Thread> mDownloadThreadMap;
	private Context mContext;

	private NotificationManager mNotifManager;
	private Notification mNotification;

	private final int DOWNFAILED = 201;
	private final int DOWNFINISH = 202;
	private final int NOTICE = 203;
	public final static int notifyId=1980;
	private final static long LEAVE_SIZE = 10240000;
	private DownloadItemDao downloadItemDao;

	private final int UPDATE_GAP = 1000;// 更新进度间隔时间为1秒
	/**********/


	private Handler mEventHandler=new Handler(){
		@Override
		public void handleMessage(Message msg)
		{
			switch(msg.what)
			{
			case DOWNFINISH:
				if(mDownloadQueue==null||mDownloadQueue.size()==0) //表示所有任务下载完
				{
					//全部任务下载完,除去通知
					mNotifManager.cancel(notifyId);
					//停止本服务
					stopSelf();
				}else
					sendNotification(false);//下载任务主体通知

				//每完成一个下载任务，通知一次
				sendSingleNotification((DownloadItem)msg.obj);
				break;
			case DOWNFAILED:
				DownloadItem item = (DownloadItem) msg.obj;
				if(item == null)
					return;
				Toast.makeText(getApplicationContext(), item.getTitle()+":"+getString(R.string.common_download_failed), Toast.LENGTH_SHORT).show();
				break;
			case NOTICE:
				String str = msg.obj.toString();
				Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
				break;
			}
		}
	};

	private LocalBinder mBinder=new LocalBinder();
	@Override
	public IBinder onBind(Intent intent) {
		LogUtil.d(TAG, "DownloadService bind");
		return mBinder;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		LogUtil.d(TAG, "service create");
		initData();
	}

	public class LocalBinder extends Binder{
		public DownloadService getService(){
			return DownloadService.this;
		}
	}

	private void toast(String str){
		Message msg = mEventHandler.obtainMessage(NOTICE);
		msg.obj = str;
		msg.sendToTarget();
	}

	/**
	 * 初始数据
	 */
	private void initData()
	{
		mContext=this;
		downloadItemDao = new DownloadItemDao(mContext,DownloadItemDao.DOWN);
		mDefBmp=((BitmapDrawable)mContext.getResources().getDrawable(R.drawable.soft_mgr_defualt_icon)).getBitmap();
		mDownloadQueue=new HashMap<String, DownloadItem>();
		mDownloadThreadMap=new HashMap<String, Thread>();

		mNotifManager=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		mNotifManager.cancel(notifyId);//将原来的下载通知除去
		//注册取消下载的监听器
		mCancelDownloadReceiver=new CancelDownloadReceiver();
		IntentFilter infilter=new IntentFilter();
		infilter.addAction(RECEIVER_CANCEL_DOWNLOAD);
		registerReceiver(mCancelDownloadReceiver, infilter);
	}

	/**
	 * 对外广播下载状态
	 * @param item
	 */
	private void broadcastStatus(DownloadItem item)
	{
		broadcastStatus(item,mContext);
	}

	/**
	 * 对外广播下载状态
	 * @param item
	 */
	private static void broadcastStatus(DownloadItem item,Context context)
	{
		Intent intent=new Intent(DOWNLOAD_STATUS_CHANGE_RECEIVER);
		intent.putExtra(DownloadItem.EXTRA_ME, item);
		context.sendBroadcast(intent);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		this.unregisterReceiver(mCancelDownloadReceiver);
		mDownloadQueue.clear();
		mDownloadQueue=null;

		if(mHandlerList!=null){
			mHandlerList.clear();
			mHandlerList=null;
		}
		if(mDownloadThreadMap!=null)
		{
			mDownloadThreadMap.clear();
			mDownloadThreadMap=null;
		}

	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		if(intent==null)
			return;
		
		DownloadItem dItem=(DownloadItem) intent.getSerializableExtra(DownloadItem.EXTRA_ME);
        if (dItem==null) {
	      	 try {
	      		 int iSoftID = intent.getIntExtra("softID",0);
	      		 String softFlag = DownloadTool.getSoftFlag(intent.getStringExtra(DownloadTool.SOFT_FLAG));
	      		 
	      		 String mUserId = null;
	      		 mUserId = SharedPreferencesUtil.getValue(this, SharedKey.Shared_UserId_Key, mUserId);
	      		
	      		 ServerDetailResult<SoftInfo> serverDetailResult = CoachSiteSoftMgrApiAccessor.getSoftAppDetail(iSoftID, mUserId, softFlag);
	      		 dItem = serverDetailResult.detailItem;
	      		 if (dItem==null) {
	      			 return ;
	      		 }
	      		 
	      		 //设置软件图标路径
				dItem.setIconPath(ImageCacheTool.url2path(dItem.getIconUrl(), SystemConst.DOWNLOAD_DIR));
	   		} catch (Exception e) {
	   			e.printStackTrace();
	   			return;
	   		}
        }		
	
		//是否为下载失败在队列中
		DownloadItem oldItem = mDownloadQueue.get(dItem.getSid());
		if(oldItem != null && oldItem.getStatus() != DownloadItem.STATUS_DOWNLOAD_FAILED){//已经在下载队列中了，不用再次下载
			toast(dItem.getTitle()+":"+getString(R.string.common_download_repeated));
			return;
		}

		if(FileUtil.getAvailableSDSize() < (dItem.getFileBytes()+LEAVE_SIZE)){
			toast(getString(R.string.common_no_enough_size));
			return;
		}

//		if(mDownloadThreadMap.keySet().size() >= MAX_THREAD){
//			toast(String.format(getString(R.string.common_too_much_thread),MAX_THREAD));
//			return;
//		}
		
		//将新任务添加到下载队列
		if(oldItem == null){
			mDownloadQueue.put(dItem.getSid(), dItem);
			downloadItemDao.addItem(dItem);
			//开始下载
			startDownload(dItem);
		}else{
			mNotifManager.cancel(Integer.parseInt(oldItem.getSid()));
			//开始下载
			startDownload(oldItem);
		}
		//通知消息栏有新任务进来
		sendNotification(true);
	}

	public static void pauseItem(DownloadItem item,Context context){
		DownloadThread downloadThread = (DownloadThread) mDownloadThreadMap.get(item.getSid());
		if(downloadThread != null){
			DownloadItem dItem = mDownloadQueue.get(item.getSid());
			item.setStatus(DownloadItem.STATUS_DOWNLOAD_PAUSE);
			dItem.setStatus(DownloadItem.STATUS_DOWNLOAD_PAUSE);
			downloadThread.setPause(true);
			broadcastStatus(dItem,context);
		}
	}

	public static void continueItem(DownloadItem item,Context context){
		DownloadThread downloadThread = (DownloadThread) mDownloadThreadMap.get(item.getSid());
		if(downloadThread != null){
			DownloadItem dItem = mDownloadQueue.get(item.getSid());
			item.setStatus(DownloadItem.STATUS_DOWNLOADING);
			dItem.setStatus(DownloadItem.STATUS_DOWNLOADING);
			downloadThread.setPause(false);
			broadcastStatus(dItem,context);
		}
	}

	/**
	 * 开始下载
	 */
	private void startDownload(DownloadItem item)
	{
		item.setStatus(DownloadItem.STATUS_DOWNLOADING);//设置状态为“正在下载”
		DownloadThread thread = new DownloadThread(item);
		thread.start();
		broadcastStatus(item);//通知前台界面，状态设置为“正在下载”
		mDownloadThreadMap.put(item.getSid(), thread);
	}


	/**
	 * 获取网络连接
	 * @param urlString
	 * @return
	 * @throws Exception
	 */
	private HttpURLConnection getConnection(String urlString) throws Exception
	{
		URL url=null;
		HttpURLConnection conn=null;
		/*	for(int i=0;i<4;i++)//尝试连接4次
		{*/
		try {
			url=new URL(urlString);
			conn=(HttpURLConnection) url.openConnection();
			conn.setDoInput(true);
			conn.setConnectTimeout(120000);//超时120秒钟
			conn.setReadTimeout(30000);//连接之后60秒钟的时间内没有读到数据，即超时
			//conn.connect();
			/*if(Thread.currentThread().isInterrupted())
					throw new InterruptedException();
				break;*/
		} catch (Exception e) {
			if(conn!=null)
				conn.disconnect();
			/*if(i==3||(e instanceof InterruptedException))//最后一次尝试失败
					throw e;*/
		}
		//	}

		return conn;
	}
	/**
	 * 
	 * @Title: getCurrentSize 
	 * @Description: 获取文件大小
	 * @param path
	 * @return     
	 * @throws
	 */
	private long getCurrentSize(String path){

		File file = FileUtil.createFile(path);
		long size = 0;
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			size = file.length();
		}
		return size;
	}

	/**
	 * 总的下载任务的通知栏提醒，每个下载任务下载完成，不归该通知
	 * @param isNewNotify //是否重新通知，重新通知会改变状态栏信息，不重新通知只会改变原来通知体的内容，状态栏不会发生变化
	 */
	private void sendNotification(boolean isNewNotify)
	{
		/*
		String appName=getString(R.string.soft_mgr_app_name);
		String taskTitle=getString(R.string.common_download_notify);
		String tikerText=taskTitle.replace("{0}", ""+mDownloadQueue.size());//"N个下载任务进行中"
		String contentTitle="【"+appName+"】"+getString(R.string.common_download_tip);
		String contentText=tikerText;//+"，"+getString(R.string.soft_mgr_click_look);
		Intent intent=new Intent(this,DownloadMainActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		PendingIntent mPendingIntent=PendingIntent.getActivity(this, 0, intent, 0);

		if(isNewNotify) //有新任务进来，重新通知
		{
			mNotification=new Notification(R.drawable.soft_mgr_download_icon, tikerText, System.currentTimeMillis());
			//mNotification=new Notification(R.drawable.down_ing, tikerText, System.currentTimeMillis());
			mNotification.flags=Notification.FLAG_NO_CLEAR; //不可清除，特所有任务下载完成，程序来进行清除
			mNotification.number=mDownloadQueue.size();
			mNotification.setLatestEventInfo(mContext, contentTitle, contentText, mPendingIntent);
		}else{
			mNotification.number=mDownloadQueue.size();
			mNotification.setLatestEventInfo(mContext, contentTitle, contentText, mPendingIntent);//"N个下载任务进行中，点击查看"
		}

		mNotifManager.notify(notifyId, mNotification);
		*/
	}

	/**
	 * 单个任务下载完成通知消息栏
	 * @param item //通知的具体下载对象
	 */
	private void sendSingleNotification(DownloadItem item)
	{
		if(item.getStatus()==DownloadItem.STATUS_NONE || item.getStatus() == DownloadItem.STATUS_UPGRADABLE) //人为中断，不进行通知
			return;
		Notification notify=new Notification();
		File file=new File(item.getFilePath());
		Uri uri = Uri.fromFile(file); 
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setDataAndType(uri, "application/vnd.android.package-archive" ); 
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

		PackageManager pm=getPackageManager();
		Bitmap innerIcon = item.getIcon();
		if(innerIcon==null)//取安装应用的图标
		{
			try {
				item.setIconPath(ImageCacheTool.url2path(item.getIconUrl(), SystemConst.DOWNLOAD_DIR));
				innerIcon = BitmapFactory.decodeFile(item.getIconPath());//取缓存图片
				if(innerIcon==null)//取安装应用的图标
				{
					Drawable d=pm.getApplicationIcon(item.getPkgName());
					if(d!=null){
						innerIcon=((BitmapDrawable)d).getBitmap();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		//上述两种都未找到时，使用默认图片
		innerIcon=innerIcon==null?mDefBmp:innerIcon;
		RemoteViews remoteViews=new RemoteViews(this.getPackageName(),R.layout.download_notify);

		remoteViews.setImageViewBitmap(R.id.im_icon, innerIcon);//拉开之后的图标
		remoteViews.setTextViewText(R.id.tv_title, item.getTitle());//拉开之后的主题标语

		String statusTitle="";//状态条的标题
		String content=""; //信息体内容
		PendingIntent mPendingIntent=null;
		if(item.getStatus()==DownloadItem.STATUS_DOWNLOADED) //下载完成
		{
			statusTitle=item.getTitle()+","+getString(R.string.common_download_ended);//"XXX,下载完成"
			content=getString(R.string.common_download_ended)+"，"+getString(R.string.soft_mgr_click_install);//"下载完成，点击安装"
		}else if(item.getStatus()==DownloadItem.STATUS_DOWNLOAD_FAILED) {//下载失败
			statusTitle=item.getTitle()+","+getString(R.string.common_download_failed);//"XXX,下载失败"
			content=getString(R.string.common_download_failed);//"下载失败"
			remoteViews.setTextColor(R.id.tv_status, Color.RED);
			intent=new Intent(this,DownloadMainActivity.class);
		}
		mPendingIntent=PendingIntent.getActivity(this, 0, intent, 0);

		//拉开之后通知体
		remoteViews.setTextViewText(R.id.tv_status, content);

		//状态栏上显示的标题
		notify.tickerText=statusTitle;
		notify.contentIntent=mPendingIntent; //点击通知执行的动作
		notify.contentView=remoteViews;
		notify.flags=Notification.FLAG_AUTO_CANCEL; //点击即 清除
		notify.icon=R.drawable.soft_mgr_upgrade_icon; //状态条上显示的图标

		if(mNotifManager!=null&&notify!=null)
		{
			int sNotifyId=Integer.parseInt(item.getSid());
			if(item.getStatus()==DownloadItem.STATUS_DOWNLOAD_FAILED){
				mNotifManager.cancel(sNotifyId);
			}
			mNotifManager.notify(sNotifyId, notify);
		}

	}

	/**
	 * 下载过程中进度条更新
	 * @param context
	 * @param position
	 * @param title
	 * @param content
	 * @param pIntent
	 * @param progress
	 */
	public void downloadRunningNotification(int position, String title, String content, PendingIntent pIntent, int progress ){
		try{
			RemoteViews view = new RemoteViews(this.getPackageName(),R.layout.download_progress_notify);
			view.setImageViewResource(R.id.widget_image, android.R.drawable.stat_sys_download);
			view.setTextViewText(R.id.percent, progress+"%");
			view.setTextViewText(R.id.widget_name, title);
			view.setProgressBar(R.id.progress, 100, progress, false);
			
			Notification notification=new Notification();
			notification.flags = Notification.FLAG_AUTO_CANCEL;
			notification.icon = android.R.drawable.stat_sys_download;
			notification.contentView = view;
			notification.contentIntent = pIntent;
			mNotifManager.notify(position, notification);
		} catch( Exception e ) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取正在下载的列表，供前台调用
	 * @return
	 */
	public List<DownloadItem> getDownloadingList()
	{
		List<DownloadItem> downloadingItems=new ArrayList<DownloadItem>();
		if(mDownloadQueue!=null&&mDownloadQueue.size()>0)
		{
			downloadingItems=new ArrayList<DownloadItem>();
			Set<String> keySet=mDownloadQueue.keySet();
			Iterator<String> iter=keySet.iterator();
			while(iter.hasNext())
			{
				String key=iter.next();
				DownloadItem item=mDownloadQueue.get(key);
				downloadingItems.add(item);
			}

		}

		return downloadingItems;
	}
	/**
	 * 注册handler,用于接收下载服务中的下载进度及状态信息
	 * @param handler
	 */
	public void registHandler(Handler handler)
	{
		if(mHandlerList==null)
			mHandlerList=new ArrayList<Handler>();
		if(mHandlerList.contains(handler))
			mHandlerList.remove(handler);
		mHandlerList.add(handler);
		mTopHanlder=handler;
	}

	/**
	 * 注销Handler
	 * @param handler
	 */
	public void unregistHandler(Handler handler)
	{
		if(mHandlerList!=null)
		{
			mHandlerList.remove(handler);
			int len=mHandlerList.size();
			if(len>0){
				mTopHanlder=mHandlerList.get(len-1);
			}
			else
				mTopHanlder=null;
		}

	}


	/**
	 * 通知activity,某个任务正在下载的状态，主要是为做进度条服务
	 */
	private void notifyDownloading(DownloadItem item, long lastUpdatedTime)
	{
		if(mTopHanlder!=null)
		{
			/*Message msg=new Message();
			msg.obj=item;
			mTopHanlder.sendMessage(msg);//通知activity,下载进度变化
			 */			
			mTopHanlder.sendEmptyMessage(0);
		}
		//更新通知栏进度
		Intent intent = new Intent( mContext, SoftMgrDetailActivity.class );
		intent.putExtra("softID", Integer.parseInt(item.getSid()));
		intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP );
		PendingIntent pIntent = PendingIntent.getActivity( mContext, Integer.parseInt(item.getSid()), intent, PendingIntent.FLAG_UPDATE_CURRENT);
		
		int progress = (int)(item.getDownloadBytes()*100/item.getFileBytes());
		if ( System.currentTimeMillis() - lastUpdatedTime > UPDATE_GAP || progress==100 ) {
			//更新进度条
			downloadRunningNotification(Integer.parseInt(item.getSid()), item.getTitle(), "下载中...", pIntent, progress);
			
			lastUpdatedTime = System.currentTimeMillis();
		}
	}

	/**
	 * 将下载记录保存到文件中去
	 * @param wpVO
	 * @throws Exception 
	 */
	private void saveHistoryToFile(DownloadItem item) throws Exception
	{
		if(!DownloadDAO.isExistHistory(item))
			DownloadDAO.addHistory(item);

	}//saveHistoryToDB

	private static int comparePkgName(String pkg1,String pkg2){
		pkg1 = pkg1.replaceAll("[^\\d\\.]", "");
		pkg2 = pkg2.replaceAll("[^\\d\\.]", "");
		String arr1[] = pkg1.split("\\.");
		String arr2[] = pkg2.split("\\.");
		int length = arr1.length>arr2.length?arr2.length:arr1.length;

		for(int i=0;i<length;i++){
			
			if ( StringUtil.isEmpty(arr1[i]) ) arr1[i] = "0";
			if ( StringUtil.isEmpty(arr2[i]) ) arr2[i] = "0";
				
			int tmp1 = Integer.parseInt(arr1[i]);
			int tmp2 = Integer.parseInt(arr2[i]);
			if(tmp1>tmp2){
				return 1;
			}else if(tmp1<tmp2){
				return -1;
			}
		}
		if(arr1.length == arr2.length)
			return 0;
		return arr1.length>arr2.length?1:-1;
	}

	public static boolean isInDownQueue(DownloadItem item){
		if(mDownloadQueue == null)
			return false;
		return mDownloadQueue.containsKey(item.getSid());
	}
	/**
	 * 获取下载状态状态标志 
	 */
	public static int getDownloadStatus(Context ctx,DownloadItem item)
	{

		if(mDownloadQueue!=null)
		{
			DownloadItem tmpVO=mDownloadQueue.get(item.getSid());
			if(tmpVO!=null) //正在下载
				return tmpVO.getStatus();
		}

		PackageManager pm=ctx.getPackageManager();
		try {
			//已安装
			PackageInfo pkgInfo=pm.getPackageInfo(item.getPkgName(), 0);
			if(pkgInfo!=null)
			{
				int status=DownloadItem.STATUS_NONE;
				//使用VersionCode 比较
				//				String remoteCode=item.getAvailVersionCode();
				//				int localCode=pkgInfo.versionCode;		
				//使用versionName 比较           暂时使用versionName比较
				boolean isInstalled;
				
				try{
					int versionCode = Integer.parseInt(item.getAvailVersionCode());
					int localCode=pkgInfo.versionCode;
					isInstalled = localCode>=versionCode;
				}catch (Exception e) {
					isInstalled = (comparePkgName(pkgInfo.versionName,item.getAvailVersion()) >= 0);
				}
				
				if(isInstalled)//本地安装的版本与网络上的版本相同或者比网络上的版本号更新，则显示已安装
					status=DownloadItem.STATUS_INSTALLED;
				else if(FileUtil.isFileExits(item.getFilePath())) //已经下载该网络版本的软件，显示已下载
					status=DownloadItem.STATUS_DOWNLOADED;
				else//本地版本号小于网络版本号，而且该软件还没下载下载，显示可以升级
					status=DownloadItem.STATUS_UPGRADABLE;
				//系统应用，则显示已安装
				boolean isSystemApp=U.isSystemPkg(ctx, pkgInfo.packageName);
				if(isSystemApp)
					status=DownloadItem.STATUS_INSTALLED;
				return status;
			}

		} catch (Exception e) {
		}

		//在未安装该软件的情况且已经下载了，显示已下载
		if(FileUtil.isFileExits(item.getFilePath())) 
			return DownloadItem.STATUS_DOWNLOADED;

		return DownloadItem.STATUS_NONE;//普通状态

	}

	/**
	 * 当前是否有正在下载的任务
	 * @return
	 */
	public static boolean hasDownloadingTask()
	{
		if(mDownloadQueue!=null&&mDownloadQueue.size()>0)
			return true;
		else
			return false;
	}

	/*---------------------------内部类区--------------------------------------*/

	/**
	 * 取消下载接收器
	 */
	private class CancelDownloadReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			DownloadItem item=(DownloadItem) intent.getSerializableExtra(DownloadItem.EXTRA_ME);
			if(item!=null)
			{
				if(mDownloadThreadMap.get(item.getSid())!=null){
					DownloadThread thread=(DownloadThread) mDownloadThreadMap.get(item.getSid());
					thread.setCancel(true);
					mDownloadThreadMap.remove(item.getSid());
				}else{
					mNotifManager.cancel(Integer.parseInt(item.getSid()));
					item.setStatus(DownloadItem.STATUS_NONE);
					PackageManager pm=mContext.getPackageManager();
					try {
						PackageInfo pkgInfo=pm.getPackageInfo(item.getPkgName(), 0);
						if(pkgInfo != null)
							item.setStatus(DownloadItem.STATUS_UPGRADABLE);
					} catch (NameNotFoundException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					Message msg=new Message();
					msg.what=DOWNFINISH;
					msg.obj=item;
					mEventHandler.sendMessage(msg);
					broadcastStatus(item);
					FileUtil.delFile(item.getFilePath());
					downloadItemDao.delete(item.getSid());
				}
				mDownloadQueue.remove(item.getSid());
				sendNotification(true);
			}
		}

	}//end CancelDownloadReceiver


	private class DownloadThread extends Thread{
		private DownloadItem item;
		private boolean pause = false;
		private boolean cancel = false;
		
		private long lastUpdatedTime = 0;
		
		public DownloadThread(DownloadItem item) {
			this.item = item;
		}
		public void setPause(boolean pause) {
			this.pause = pause;
		}
		public void setCancel(boolean cancel) {
			this.cancel = cancel;
		}
		
		@Override
		public void run() {
			Thread.setDefaultUncaughtExceptionHandler(new UncautchHandler());
			//连接网络，开始下载并保存
			lastUpdatedTime = 0;
			
			//CoachSiteSoftMgrApiAccessor.downAppCount(item.getSid());
			CoachSiteSoftMgrApiAccessor.downAppGameCount(item.getSid(),"1", mContext);
			
			saveApk(item);

			//每完成一个下载任务，通知消息栏改变下载任务状态
			Message msg=new Message();
			msg.what=DOWNFINISH;
			msg.obj=item;
			mEventHandler.sendMessage(msg);
			mDownloadThreadMap.remove(item.getSid()); //移除下载线程
			
			if(item.getStatus() != DownloadItem.STATUS_DOWNLOAD_FAILED){
				mDownloadQueue.remove(item.getSid());
				downloadItemDao.delete(item.getSid());
			}
		}

		/**
		 * 保存文件到SDCARD
		 * @param urlString
		 */
		private void saveApk(DownloadItem item)
		{
			HttpURLConnection conn=null;
			InputStream in=null;
			//FileOutputStream fos=null;
			String urlString=item.getDownloadUrl();
			//File outFile=null;
			RandomAccessFile outFile =null;
			long currentSize =0;
			boolean  isReConn = false;
			int currentTimes =0;
			boolean isStop = false;
			int download_bytes =8192;
			int update_bytes =2048;
			try {
				LogUtil.d(TAG, "/*****************************/");
				LogUtil.d(TAG, "filepath="+item.getFilePath());
				//LogUtil.d(TAG, "totalsize="+item.getFileBytes());
				currentSize = getCurrentSize(item.getFilePath());
				//LogUtil.d(TAG, "currentSize="+currentSize);
				conn=getConnection(urlString);
				/**** 设置断点 **/
				String sProperty = "bytes=" + currentSize + "-";
				conn.setRequestProperty("RANGE", sProperty);
				conn.connect();

				LogUtil.d(TAG, "totalsize="+conn.getContentLength());
				item.setFileBytes(conn.getContentLength());
				outFile = new RandomAccessFile(item.getFilePath(), "rw");
				outFile.seek(currentSize);
				/****/
				in=conn.getInputStream();
				byte[] tmpBytes=new byte[download_bytes];//8K
				int len=-1;
				long totalBytes=0;//记录当前已读取的字节总数

				while(!isStop){
					/**加入重连机制**/
					if (isReConn && currentTimes<SystemConst.CONNETION_TIMES) { 
						try {
							conn=getConnection(urlString);
							/**** 设置断点 **/
							currentSize = getCurrentSize(item.getFilePath());
							sProperty = "bytes=" + currentSize + "-";
							conn.setRequestProperty("RANGE", sProperty);
							conn.connect();

							in=conn.getInputStream();
							outFile.seek(currentSize);
							isReConn = false;
						} catch (Exception e) {
							LogUtil.e(TAG, "get responseCode fail");
							currentTimes++;
							isReConn = true;
							try {
								Thread.sleep(SystemConst.CONNETION_INTERVAL);
								in.close();
								conn.disconnect();
							} catch (Exception ex) {
							}
							continue;
						}
					}else if(currentTimes == SystemConst.CONNETION_TIMES){
						throw new Exception();
					}
					/****/

					// 下载
					try {
						len = in.read(tmpBytes, 0, download_bytes);
						if (len > 0) {
							outFile.write(tmpBytes, 0, len);
							totalBytes+=len; //累加已读取的字节总数
							currentSize+=len;
							//LogUtil.d(TAG, "currentSize="+currentSize);
							//item.getFileBytes()/15
							if((totalBytes-item.getDownloadBytes())>=update_bytes||totalBytes==item.getFileBytes())
							{
								item.setDownloadBytes(totalBytes);
								notifyDownloading(item,lastUpdatedTime);//通知activity,下载进度变化
							}
							if(totalBytes==item.getFileBytes()){
								isStop = true;
								break;
							}

						} 
					} catch (Exception e) {
						LogUtil.e(TAG, "get responseCode fail");
						isReConn = true;
						try {
							Thread.sleep(SystemConst.CONNETION_INTERVAL);
							in.close();
							conn.disconnect();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
						continue;
					}

					while(pause){
						Thread.sleep(1000);
						if(cancel){
							throw new InterruptedException();
						}
					}

					//线程被干扰掉，一般是人为取消下载时触发的
					if(cancel){
						throw new InterruptedException();
					}
				}

				//下载时间
				SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
				item.setDownloadTime(sdf.format(new Date()));
				//添加到下载历史记录文件中
				saveHistoryToFile(item);
				//下载成功后，设置活动状态为"已下载"
				item.setStatus(DownloadItem.STATUS_DOWNLOADED);
				
			} catch (Exception e) {

				e.printStackTrace();
				if(!(e instanceof InterruptedException)) 
				{
					Message msg=new Message();
					msg.what=DOWNFAILED;
					msg.obj=item;
					mEventHandler.sendMessage(msg);
					item.setStatus(DownloadItem.STATUS_DOWNLOAD_FAILED);//表示下载失败
				}else{//人为中断
					item.setStatus(DownloadItem.STATUS_NONE);
					PackageManager pm=mContext.getPackageManager();
					try {
						PackageInfo pkgInfo=pm.getPackageInfo(item.getPkgName(), 0);
						if(pkgInfo != null)
							item.setStatus(DownloadItem.STATUS_UPGRADABLE);
					} catch (NameNotFoundException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					/*if(outFile!=null && outFile.exists())
						outFile.delete();//出现异常时将下载未完成的文件删除
					 */
					File file = new File(item.getFilePath());
					if(file!=null && file.exists()){
						file.delete();
					}
				}
			} finally{
				isStop = true;
				//下载队列中移去一个任务,不管下载成功失败，下载结束就移除任务
				broadcastStatus(item);//通知activity,该任务下载结束
				try {
					/*if(fos!=null)
						fos.close();*/
					if(outFile!=null){
						outFile.close();
					}
					if(in!=null)
						in.close();
					if(conn!=null)
						conn.disconnect();
				} catch (Exception e2) {
				}
			}

		}
	}

	/**
	 * 线程未捕捉的错误处理
	 */
	private class UncautchHandler implements UncaughtExceptionHandler{

		@Override
		public void uncaughtException(Thread thread, Throwable ex) {
			ex.printStackTrace();
		}

	}//end UncautchHandler;
}
































